package com.gupaoedu.springframework.mvcframework.beans.support;

import com.gupaoedu.springframework.mvcframework.beans.config.MyBeanDefinition;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * projectName: my-springframwork
 * packageName: com.gupaoedu.springframework.mvcframework.beans.support
 * Created: 2019/4/11.
 * Auther: baifc
 * Description:
 */
public class MyBeanDefinitionReader {

    private Properties properties = new Properties();

    private List<String> registryBeanClasses = new ArrayList<>();

    private static final String SCAN_PACKAGE = "scanPackage";

    public MyBeanDefinitionReader(String... locations) {
        InputStream inputStream = this.getClass()
                .getClassLoader()
                .getResourceAsStream(locations[0].replace("classpath:", ""));
        try {
            properties.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        doScanner(properties.getProperty(SCAN_PACKAGE));
    }

    private void doScanner(String packageName) {

        String packagePath = packageName.replace(".", "/");


        URL url = this.getClass().getClassLoader().getResource(packagePath.replaceAll("/+", "/"));

        if (url == null) {
            return;
        }
        File classPath = new File(url.getFile());


        for (File file : classPath.listFiles()) {
            if (file.isDirectory()) {
                doScanner(packageName + "." + file.getName());
            } else {
                if (!file.getName().endsWith(".class")) {
                    continue;
                } else {
                    registryBeanClasses.add(packageName + "." + file.getName().replace(".class", ""));
                }
            }
        }
    }


    public List<MyBeanDefinition> loadBeanDefinitions() throws Exception {
        List<MyBeanDefinition> beanDefinitions = new ArrayList<>();

        for (String className : registryBeanClasses) {
            Class<?> clazz = Class.forName(className);
            if (clazz.isInterface()) {
                continue;
            }

            beanDefinitions.add(doCreateBeanDefinition(toLowerFirstCase(clazz.getSimpleName()), clazz.getName()));

            Class<?> [] interfaces = clazz.getInterfaces();
            for (Class<?> inter : interfaces) {
                //如果是多个实现类，只能覆盖
                //为什么？因为Spring没那么智能，就是这么傻
                //这个时候，可以自定义名字 //TODO: 为啥不是getSimpleName?
                beanDefinitions.add(doCreateBeanDefinition(inter.getName(), clazz.getName()));
            }

        }

        return beanDefinitions;
    }

    private MyBeanDefinition doCreateBeanDefinition(String factoryBeanName, String beanClassName) {
        MyBeanDefinition beanDefinition = new MyBeanDefinition();
        beanDefinition.setFactoryBeanName(factoryBeanName);
        beanDefinition.setBeanClassName(beanClassName);

        return beanDefinition;
    }


    private String toLowerFirstCase(String simpleName) {
        char [] chars = simpleName.toCharArray();
        //之所以加，是因为大小写字母的ASCII码相差32，
        // 而且大写字母的ASCII码要小于小写字母的ASCII码
        //在Java中，对char做算学运算，实际上就是对ASCII码做算学运算
        chars[0] += 32;
        return String.valueOf(chars);
    }

    public Properties getProperties() {
        return properties;
    }


}
